#include "stdafx.h"
#include "CMessageSendByEvent.h"

CMessageSendByEvent::CMessageSendByEvent(HANDLE cevent,HANDLE revent,HANDLE mapobj)
{
	PVOID mapaddr=NULL;

	m_stream=NULL;
	m_sendevent=cevent;
	m_recvevent=revent;
	m_mapobj=mapobj;
	if(mapobj)
	{
		if((mapaddr=::MapViewOfFile(m_mapobj,FILE_MAP_WRITE, 0, 0,0))!=NULL)
		{
			m_stream= new strstream((char*)mapaddr,STACK_MAX_SIZE);
		}
	}
}

BOOL CMessageSendByEvent::Open(PCHAR* names)
{
	PVOID mapaddr=NULL;

	try
	{
		if(names!=NULL)
		{
			if((m_sendevent=OpenEventA(EVENT_ALL_ACCESS,FALSE,names[0]))!=NULL)
			{
				if((m_recvevent=CreateEventA(NULL,FALSE,FALSE,names[1]))!=NULL)
				{
					if((m_mapobj=OpenFileMappingA(FILE_MAP_WRITE,FALSE,names[2]))!=NULL)
					{
						if(m_mapobj)
						{
							if((mapaddr=::MapViewOfFile(m_mapobj,FILE_MAP_ALL_ACCESS, 0, 0,0))!=NULL)
							{
								m_stream= new strstream((char*)mapaddr,STACK_MAX_SIZE);
								return TRUE;
							}
						}
					}
					else
					{
						CloseHandle(m_sendevent);
						CloseHandle(m_recvevent);
					}
				}
				else
				{
					CloseHandle(m_sendevent);
				}
			}
		}
	}
	catch(...)
	{
	}
	return FALSE;
}

CMessageSendByEvent::~CMessageSendByEvent()
{
	if((m_sendevent!=NULL)&&(m_stream!=NULL))
	{
		LONGLONG l=-1;
		m_stream->write((char*)&l,sizeof(LONGLONG));
		SetEvent(m_sendevent);
	}
	if(m_stream&&m_mapobj)
	{
		m_stream->seekg(0);
		UnmapViewOfFile(m_stream->str());
		delete m_stream;
		::CloseHandle(m_mapobj);
	}
	if(m_sendevent) ::CloseHandle(m_sendevent);
	if(m_recvevent)  ::CloseHandle(m_recvevent);
}

void CMessageSendByEvent::Close()
{
	LONGLONG l=-1;
	try
	{
		m_stream->seekp(0);
		m_stream->write((char*)&l,sizeof(LONGLONG));
		if(m_recvevent) SetEvent(m_recvevent);
	}
	catch(...)
	{
	}
}

LONGLONG CMessageSendByEvent::Send(IMessage* message)
{
	LONGLONG qwRet=0;
	if(m_stream)
	{
		m_stream->seekp(0);
		m_stream->write((char*)&qwRet,sizeof(qwRet));
		if(message->PutData(m_stream))
		{
			if((m_sendevent!=NULL)&&(m_recvevent!=NULL))
			{
				::SetEvent(m_sendevent);
				DWORD dwRet=WaitForSingleObject(m_recvevent, INFINITE);				
				if (dwRet == WAIT_OBJECT_0)
				{
					m_stream->seekg(0);
					m_stream->read((char*)&qwRet,sizeof(qwRet));
				}
			}
		}
	}
	return qwRet;
}